import { RedisNamespace } from '../config/config.interface';
import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { RedisService } from "@liaoliaots/nestjs-redis";
import { Redis } from "ioredis";
import { Reflector } from '@nestjs/core';
import { LoggerService } from '@/common/logger/logger.service';
import { UserModel } from '@/module/user/user.model';

@Injectable()
export class UserAuthGuard implements CanActivate {
  userLoginRedisClient: Redis;
  
  constructor(
    private readonly redisService: RedisService,
  private readonly reflector: Reflector,
    private readonly loggerService: LoggerService,
  ) {
    this.userLoginRedisClient = this.redisService.getClient(
      RedisNamespace.user_login,
    );
  }

  static authExpireSecond = 7 * 24 * 60 * 60; // 一周

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();

    const token = request.headers.token;
    if (!token) {
      throw new UnauthorizedException();
    }
    const userStr = await this.userLoginRedisClient.get(token);
    if (!userStr) {
      throw new UnauthorizedException();
    }
    const user: UserModel = JSON.parse(userStr);
    const userTypes = this.reflector.get<string[]>('userTypes', context.getHandler());
    if (userTypes && !userTypes.includes(user.userType)) {
      this.loggerService.warn(`Request over permission userUuid: ${user.uuid}`)
      return false;
    }
    this.userLoginRedisClient.expire(token, UserAuthGuard.authExpireSecond); // 异步刷新session时间
    request.user = user;
    return true;
  }
}

